<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Cargo Live Map</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>

    <link rel="stylesheet" href="#{resource['/css/dd.css']}"/>

    <link rel="stylesheet"
          href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css"/>

    <link rel="stylesheet"
          href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
          integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
          crossorigin=""/>
    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
            integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
            crossorigin=""/>

    <script type="text/javascript">
        const locationName = {
            "CNHKG": "Hong Kong",
            "AUMEL": "Melbourne",
            "SESTO": "Stockholm",
            "FIHEL": "Helsinki",
            "USCHI": "Chicago",
            "JNTKO": "Tokyo",
            "DEHAM": "Hamburg",
            "CNSHA": "Shanghai",
            "NLRTM": "Rotterdam",
            "SEGOT": "Gothenburg",
            "CNHGH": "Hangzhou",
            "USNYC": "New York",
            "USDAL": "Dallas"
        };

        const routingStatusName = {
            "NOT_ROUTED": "Not routed",
            "ROUTED": "Routed",
            "MISROUTED": "Misrouted"
        };

        const transportStatusName = {
            "NOT_RECEIVED": "Not received",
            "IN_PORT": " In port",
            "ONBOARD_CARRIER": "Onboard carrier",
            "CLAIMED": "Claimed",
            "UNKNOWN": "Unknown"
        };

        // TODO See if there is a service to get the latitude/longitude
        // data from.
        const latitude = {
            "CNHKG": 22,
            "AUMEL": -38,
            "SESTO": 59,
            "FIHEL": 60,
            "USCHI": 42,
            "JNTKO": 36,
            "DEHAM": 54,
            "CNSHA": 31,
            "NLRTM": 52,
            "SEGOT": 58,
            "CNHGH": 30,
            "USNYC": 41,
            "USDAL": 33
        };

        const longitude = {
            "CNHKG": 114,
            "AUMEL": 145,
            "SESTO": 18,
            "FIHEL": 25,
            "USCHI": -88,
            "JNTKO": 140,
            "DEHAM": 10,
            "CNSHA": 121,
            "NLRTM": 5,
            "SEGOT": 12,
            "CNHGH": 120,
            "USNYC": -74,
            "USDAL": -97
        };

        //  load the icons for the map
        const greenIcon = new L.Icon({
            iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png',
            shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
            iconSize: [25, 41],
            iconAnchor: [12, 41],
            popupAnchor: [1, -34],
            shadowSize: [41, 41]
        });

        const greyIcon = new L.Icon({
            iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-grey.png',
            shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
            iconSize: [25, 41],
            iconAnchor: [12, 41],
            popupAnchor: [1, -34],
            shadowSize: [41, 41]
        });

        const redIcon = new L.Icon({
            iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png',
            shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
            iconSize: [25, 41],
            iconAnchor: [12, 41],
            popupAnchor: [1, -34],
            shadowSize: [41, 41]
        });

        const blackIcon = new L.Icon({
            iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-black.png',
            shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
            iconSize: [25, 41],
            iconAnchor: [12, 41],
            popupAnchor: [1, -34],
            shadowSize: [41, 41]
        });

        const goldIcon = new L.Icon({
            iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-gold.png',
            shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
            iconSize: [25, 41],
            iconAnchor: [12, 41],
            popupAnchor: [1, -34],
            shadowSize: [41, 41]
        });

        const colorCodes = {
            "NOT_ROUTED": greyIcon,
            "MISROUTED": redIcon,
            "NOT_RECEIVED": goldIcon,
            "IN_PORT": greenIcon,
            "ONBOARD_CARRIER": greenIcon,
            "MISDIRECTED": redIcon,
            "AT_DESTINATION": blackIcon,
            "CLAIMED": blackIcon,
            "UNKNOWN": redIcon
        };
    </script>
</head>

<body style="background-color: white">
<div>
    <div id="map"
         style="height: 600px; border: #FFF; border-style: solid; border-width: 8px;">
    </div>

    <br/>
    <br/>
    <div id='connected' class='status'>
        <p id='status' class='status_constent'>Offline</p>
    </div>
</div>

<script type="text/javascript">
    const statusBox = document.getElementById('connected');
    statusBox.style.cursor = 'pointer';
    statusBox.onclick = function () {
        location.reload(true);
    };
</script>
<script type="text/javascript">
    function init() {
        // TODO [DDD] This extra invocation really isn't necessary. We should get all the
        // necessary data from the Cargo view adapter.
        fetch('/cargo-tracker/rest/cargo')
            .then(response => response.json())
            .then(cargos => {
                const coordinates = [];

                for (const cargo of cargos) {
                    const locationCode = (cargo.transportStatus == 'NOT_RECEIVED') ? cargo.origin : cargo.lastKnownLocation;

                    let statusCode = 'NOT_RECEIVED';
                    if ((cargo.routingStatus === 'NOT_ROUTED') || (cargo.routingStatus === 'MISROUTED')) {
                        statusCode = cargo.routingStatus;
                    } else if (cargo.misdirected === true) {
                        statusCode = 'MISDIRECTED';
                    } else if (cargo.atDestination === true) {
                        statusCode = 'AT_DESTINATION';
                    } else {
                        statusCode = cargo.transportStatus;
                    }

                    coordinates.push(
                        {
                            position: {
                                lon: longitude[locationCode] + (Math.floor((Math.random() * 3) - 3)),
                                lat: latitude[locationCode] + (Math.floor((Math.random() * 3) - 3)),
                            },
                            trackingId: cargo.trackingId,
                            style: colorCodes[statusCode]
                        }
                    );
                }

                const map = L.map('map').setView({lon: 0, lat: 0}, 2);

                // add the OpenStreetMap tiles
                L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                    maxZoom: 19,
                    attribution: '&#xA9;; &lt;a href="https://openstreetmap.org/copyright">OpenStreetMap contributors&lt;/a>'
                }).addTo(map);

                // show the scale bar on the lower left corner
                L.control.scale().addTo(map);

                const applicationPath = window.location.pathname.split('/')[1];
                const trackingBaseUri = "http://" + document.location.host + "/" + applicationPath + "/admin/show.xhtml?trackingId=";
                const winHeight = window.innerHeight;
                const winWidth = window.innerWidth;
                const winDimensions = "height=" + winHeight + ",width=" + winWidth;

                coordinates.forEach((coord, index) => {
                    const popupContent = 'Tracking ID: ' + cargos[index].trackingId + '&lt;br/>' +
                        'Routing Status: ' + routingStatusName[cargos[index].routingStatus] + '&lt;br/>' +
                        'Misdirected: ' + (cargos[index].misdirected ? "Yes" : "No") + '&lt;br/>' +
                        'Transport Status: ' + transportStatusName[cargos[index].transportStatus] + '&lt;br/>' +
                        'At Destination: ' + (cargos[index].atDestination ? "Yes" : "No") + '&lt;br/>' +
                        'Origin: ' + locationName[cargos[index].origin] + '&lt;br/>' +
                        'Last known location: ' + locationName[cargos[index].lastKnownLocation];

                    L.marker(coord['position'], {icon: coord.style})
                        .bindTooltip(popupContent)
                        .addTo(map)
                        .on('click', () => {
                            const trackingUri = trackingBaseUri + coord.trackingId;
                            window.open(trackingUri, "winMap", winDimensions);
                        });
                });
            })
            .catch(e => console.error("cannot fetch cargos", e));
    }

</script>
<script type="text/javascript">
    window.onload = function () {
        const applicationPath = window.location.pathname.split('/')[1];
        const socketUri = "ws://" + document.location.host + "/" + applicationPath + "/tracking";
        const socket = new WebSocket(socketUri);

        const status = document.getElementById("status");

        socket.onopen = function (event) {
            status.innerHTML = "online";
        }

        socket.onmessage = function (event) {
            status.innerHTML = "mesage";
            location.reload(true);
        };

        socket.onclose = function (event) {
            status.innerHTML = "offline";
        };

        init();
    }
</script>
</body>
</html>
